package com.bfly.common.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.Map;

/**
 * JWT工具类
 *
 * @author 长沙商脉科技有限公司
 * @date 2020/12/28 13:36
 */
public class JwtUtil {

    private static Logger logger = LoggerFactory.getLogger(JwtUtil.class);
    private static final String KEY = "BFly-Shop-AUTH_KEY_2020_CSSMKJYXGS";

    /**
     * 生成Token 默认30分钟
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/12/28 13:37
     */
    public static String generateToken(int id, String subject, Long exp, Map<String, Object> param) {
        Date now = new Date();
        JWTCreator.Builder builder = JWT.create();
        if (param != null) {
            builder.withClaim("data", param);
        }
        if (exp == null || exp <= 0) {
            exp = 30 * 60 * 1000L;
        }
        exp = exp + now.getTime();
        Date expDate = new Date(exp);
        String token = builder
                .withIssuer(String.valueOf(id))
                // 签发时间
                .withIssuedAt(now)
                // 过期时间
                .withExpiresAt(expDate)

                .withSubject(subject)
                // 签名
                .sign(Algorithm.HMAC256(KEY));
        return token;
    }


    /**
     * 后端用户token生成
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/12/28 14:34
     */
    public static String generateTokenForAdmin(int id,String userName) {
        return generateToken(id,userName, 2 * 60 * 60 * 1000L, null);
    }

    /**
     * 判断是否需要重新生成Token，token需要在有效期内定期生成
     * 周期为失效期的一半例如：失效期为30分钟，则超过15分钟就要生成一次
     *
     * @author andy_hulibo@163.com
     * @date 2020/4/18 12:20
     */
    public static boolean needReNewToken(String token) {
        DecodedJWT decode = getJwtData(token);
        // 过期时间
        Date expired = decode.getExpiresAt();
        // 签发时间
        Date issuedAt = decode.getIssuedAt();
        long millis = expired.getTime() - System.currentTimeMillis();

        // 刷新周期是token有效期的一半
        long refreshMillis = (expired.getTime() - issuedAt.getTime()) / 2;
        return millis < refreshMillis;
    }

    public static DecodedJWT getJwtData(String token) {
        DecodedJWT decode = JWT.decode(token);
        return decode;
    }

    /**
     * Token验证
     *
     * @author andy_hulibo@163.com
     * @date 2020/3/25 0025 上午 10:50
     */
    public static boolean validateToken(String token) {
        boolean flag;
        try {
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(KEY)).build();
            jwtVerifier.verify(token);
            flag = true;
        } catch (Exception e) {
            flag = false;
            logger.error(e.getMessage());
        }
        return flag;
    }
}
